package server

import (
	"context"
	"fmt"
	"longmen/server/config/global"
	"longmen/server/internal/api"
	"longmen/server/internal/services/consumers/publisher"
	time2 "longmen/server/pkg/common/helper/timehelper"
	utils2 "longmen/server/pkg/common/helper/util"
	"longmen/server/pkg/db/mysql"
	"longmen/server/pkg/db/mysql/db_live"
	"longmen/server/pkg/db/mysql/db_main"
	"longmen/server/pkg/db/mysql/models/models_live"
	"longmen/server/pkg/db/mysql/models/models_main"
	"longmen/server/pkg/db/redis/cache"
	"longmen/server/pkg/grpc_client"
	"longmen/server/pkg/protobuf"
	"time"

	global2 "longmen/server/config/global"
	messages2 "longmen/server/internal/rpc/tencentim/messages"
	"longmen/server/pkg/common/api_models"
)

// 屏蔽操作权限检测
/***
查目标用户是不是被禁了，禁了多久，原因是啥
*/
func (s *Server) Permission(c context.Context, req *protobuf.PermissionReq) (*protobuf.PermissionResp, error) {

	var pr protobuf.PermissionResp

	// 目标用户信息
	user, err := mysql.GetUserParam(map[string]interface{}{"id": req.TargetUserId})
	pr.Permit = 2
	if err != nil {
		return &pr, nil
	}

	pr.TargetUserAvatar = user.Avatar
	pr.TargetUserName = user.NickName

	userlv, _ := getUserLevel(user.Point)
	pr.TargetUserLevel = int32(userlv.Level)

	banInRoom := &models_live.LiveRoomBanneduser{}
	err = global.Live().Model(&models_live.LiveRoomBanneduser{}).Where(
		"uid=? and (anchorid=? or anchorid=0) and (ban_time>?)",
		req.TargetUserId, req.AnchorId, time.Now().Unix()).
		Order("ban_time desc").Limit(1).
		Find(banInRoom).Error

	/*if err != nil || (banInRoom.Id == 0) {
		global.Log.Warn("=== Permission", err)
		pr.Permit = 2 //todo 这个permit好像没有用了 要和前端确认
		return &pr, nil
	}*/
	if banInRoom.Id > 0 {
		pr.TargetUserIsBanned = 1 //已禁言
		pr.Reason = banInRoom.Reason
		pr.TimeMsg = time2.Time2Msg(banInRoom.BanTime - time.Now().Unix())
	} else {
		pr.TargetUserIsBanned = 2
	}

	// 贵族
	record, err := db_main.GetNobleRecordByUid(int(req.TargetUserId))
	if err != nil {
		return nil, err
	}
	pr.TargetUserVipTitle = int32(record.NobleId)

	if req.UserId != req.AnchorId {
		managerUser, err := db_live.GetLiveRoomManagerParam(map[string]interface{}{"mgrid": req.UserId})
		if err != nil {
			return &pr, err
		}
		if managerUser.Id < 1 {
			return &pr, nil
		}
		if managerUser.Anchorid != 0 && managerUser.Anchorid != int(req.AnchorId) { //不是超管和该房间管理
			return &pr, nil
		}
		pr.Permit = 3 //房管
	} else {
		pr.Permit = 1
	}
	return &pr, nil
}

func getUserLevel(userPoint int) (*api_models.Level, error) {
	fName := "GetUserLevel"
	var upgradePoint uint32 //指定等级所需经验
	var process uint32      //当前等级进度
	var difference uint32   //获取用户经验值,计算出level
	var remainder uint32    //获取用户经验值,计算出level
	rule, level, err := calculateUserLevel(uint32(userPoint))
	if err != nil {
		return nil, fmt.Errorf("%s %s", utils2.Convert(fName), err)
	}

	for i := 0; i < len(rule); i++ {
		if level == rule[i].Level-1 {
			upgradePoint = rule[i].Point
			if i > 0 {
				process = uint32(userPoint - int(rule[i-1].Point))
				difference = rule[i].Point - rule[i-1].Point
				break
			}
			process = uint32(userPoint) //0级别
			difference = rule[i].Point
			break
		}
	}

	if upgradePoint > uint32(userPoint) {
		remainder = upgradePoint - uint32(userPoint)
	}

	return &api_models.Level{
		Level:        level,
		Point:        uint32(userPoint),
		UpgradePoint: upgradePoint,
		Process:      process,
		Difference:   difference,
		Remainder:    remainder,
	}, nil
}

func calculateUserLevel(point uint32) ([]*models_main.UserLevelRule, uint8, error) {
	var (
		err   error
		level uint8
		fName = "CalculateUserLevel"
		rule  []*models_main.UserLevelRule
	)
	level = 1
	if rule, err = cache.GetUserLevelRule(); err != nil {
		return nil, 0, fmt.Errorf("%s %s", utils2.Convert(fName), err.Error())
	}

	for i := 0; i < len(rule)-1; i++ {
		for j := 0; j < len(rule)-1-i; j++ {
			if rule[j].Level > rule[j+1].Level {
				rule[j], rule[j+1] = rule[j+1], rule[j]
			}
		}
	}

	for i := 0; i < len(rule); i++ {
		if point >= rule[i].Point {
			level = rule[i].Level
		} else {
			break
		}
	}

	return rule, level, nil
}

func (s *Server) ChatConfig(c context.Context, req *protobuf.Empty) (*protobuf.ChatConfigResp, error) {
	var r = &protobuf.ChatConfigResp{}
	cacheKey := "ChatPloy"
	cache.GetCachedData(cacheKey, r)
	if r.Id > 0 {
		return r, nil
	}
	err := global.GetR().Table("db_config_chat_ploy").Scan(&r).Error
	if err == nil || r.Id > 0 {
		cache.SetCacheData(cacheKey, r, time.Second*60)
	}
	return r, err
}

func (s *Server) AdminPub(c context.Context, req *protobuf.AdminPubReq) (*protobuf.AdminPubResp, error) {
	resp := &messages2.RoomUserSayMessageToNats{
		SentMessageStruct: messages2.SentMessageStruct{Type: messages2.RoomUserSayMessageType},
		Id:                cache.GetChatAutoId(),
		Content:           req.Content,
		UserId:            261474,
		ClientName:        req.Name,
		Level:             5,
		Props:             nil,
		RoomId:            int(req.RoomId),
		Role:              3,
		CreateTime:        time.Now().Unix(),
	}
	global2.PublisherTxChat.BroadCast(publisher.AutoChat, resp)
	base := &api.Controller{}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	_, err := grpc_client.GrpcTencentImClient.WriteChatHistory(ctx, &protobuf.WriteChatHistoryReq{
		ChatId:     resp.Id,
		RoomId:     int32(req.RoomId),
		Uid:        int32(resp.UserId),
		Content:    resp.Content,
		Level:      int32(resp.Level),
		ClientName: resp.ClientName,
		Role:       resp.Role,
	})
	if err != nil {
		global2.Log.Errorf("AdminPub err:%v", err)
		return &protobuf.AdminPubResp{
			Status: 0,
		}, err
	}

	return &protobuf.AdminPubResp{
		Status: 1,
	}, nil
}
